/**
 *  @file SSLContext.h
 */
#ifndef _SSLCONTEXT_H_
#define _SSLCONTEXT_H_

#include "../../common/BaseObject.h"
#include "../../text/CFString.h"
#include "SSLCallbacks.h"

namespace cppflib
{

namespace net
{

namespace ssl
{

class SSLSocket;
class SSLServerSocket;

/**
 *  SSL Context -- a class to init SSL env and create SSL socket for client and server
 */
class _DLLAPI SSLContext : public BaseObject
{
private:
    ptrany_t sslCtx;
    bool isServerCtx; ///< context for server or not
    ISSLPrivateKeyPwdCallback *pPrivateKeyPwdCb;
    ISSLFindMatchingHostNameCallback *pFindMatchingHostNameCb;

private:
    void Close();
    void ReleaseBeforeThrowing();
    
public:
    SSLContext();
    SSLContext(bool isServer, const CFString &pathToPEMFileWithRootCerts, bool needPeerAuth);
    virtual ~SSLContext(void);

    bool SetCertChain(const CFString &pathToPEMFileWithCertChain, ISSLPrivateKeyPwdCallback *pPrivateKeyPwdCb);
    bool SetServerNameCallback(ISSLFindMatchingHostNameCallback *pFindMatchingHostNameCb);
    bool NeedPeerAuthentication();
    
    SSLSocket *CreateClientSocket(SSLSocket *pSSLSock, ISSLPeerCertCallback *pPeerCertCb);
    SSLServerSocket *CreateServerSocket(ISSLPeerCertCallback *pPeerCertCb = NULL);

    ptrany_t GetInternalContext();

    PUBLIC CFString GetOpenSSLVersion();
    PUBLIC u32_t GetOpenSSLVersionNumber();
};


} // end of namespace ssl

} // end of namespace net

} // end of namespace cppflib


#endif
